# -*- coding: utf-8 -*-
from datetime import datetime

from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.template.context import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordChangeForm
from django.http import HttpResponseRedirect, Http404
from django.db.models import Q
from django.core.paginator import Paginator
from django.contrib import messages

from mdcssport.mdcsapp.models import PlayerUserProfile, Match, PointsLog, News
from mdcssport.mdcsapp.forms import PlayerUserProfileForm, FilterUserForm, UserSelect
from mdcssport.mdcsapp.statistics import UserMatchStatistics

"""
Indeks strana, prikazuje trenutno stanje na tabeli
"""
def index(request):
    # poslednjih 5 vesti
    news_list = News.objects.order_by('-date_updated')[:5]
    news_paginator = Paginator(news_list, 10)
    news = news_paginator.page(1)

    return render_to_response('index.html', {"news": news},
        context_instance=RequestContext(request))

@login_required
def profile(request):
    user = request.user.get_profile()

    if request.method == "POST":
        form = PlayerUserProfileForm(request.POST, request.FILES, instance = user)
        if form.is_valid():
            user = form.save(commit=False)
            user.save()
            messages.add_message(request, messages.INFO, "Profil uspešno promenjen")
            return HttpResponseRedirect(reverse('mdcssport.mdcsapp.views.profile'))
    else:
        form = PlayerUserProfileForm(instance = user)
    return render_to_response('profile.html', {"form": form},
        context_instance=RequestContext(request))

@login_required
def profile_password_change(request):
    """
    Profil strana (za sada samo menjanje passworda).
    Inace, nisam ja Django guru da napisem ovo ispod, nego je ovo ukradeno iz
    django.contrib.auth.views.password_change f-je, a iskopirano je da bi mogao
    da setujem poruku korisniku da je password promenjen, jer Django to ne radi:/
    """
    if request.method == "POST":
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            form.save()
            messages.add_message(request, messages.INFO, "Lozinka uspešno promenjena")
            return HttpResponseRedirect(reverse('mdcssport.mdcsapp.views.profile_password_change'))
    else:
        form = PasswordChangeForm(request.user)
    return render_to_response('profile_password_change.html', {'form': form}, context_instance=RequestContext(request))

def chess(request):
    return render_to_response('chess.html', {}, context_instance=RequestContext(request))

def tf(request):
    return render_to_response('tf.html', {}, context_instance=RequestContext(request))

def football(request):
    return render_to_response('football.html', {}, context_instance=RequestContext(request))

def basket(request):
    return render_to_response('basket.html', {}, context_instance=RequestContext(request))

def standings_all(request):
    return render_to_response('standings_all.html', {}, context_instance=RequestContext(request))

def standings(request, game_type):
    game_type_id = 1
    game_name = None
    point_column = None
    if game_type == "chess":
        game_type_id = 1
        game_name = "šah"
        point_column = 'chess_points'
    elif game_type == "table_football":
        game_type_id = 2
        game_name = "stoni fudbal"
        point_column = 'tf_points'
    elif game_type == "football":
        game_type_id = 3
        game_name = "fudbal"
        point_column = 'football_points'
    elif game_type == "basketball":
        game_type_id = 4
        game_name = "basket"
        point_column = 'basket_points'
    else:
        raise Http404('Unknown game type "%s"' % game_type)

    show_all_users = request.GET.get('all_users', '')
    not_only_mdcs = request.GET.get('not_only_mdcs', '')
    not_active = request.GET.get('not_active', '')

    form = FilterUserForm({'all_users': show_all_users == "on",
                           'not_only_mdcs': not_only_mdcs == "on",
                           'not_active': not_active == "on"})
    users = PlayerUserProfile.objects
    if not show_all_users == 'on':
        home_users = Q(homes__game_type=game_type_id, homes__winner__isnull=False)
        away_users = Q(aways__game_type=game_type_id, aways__winner__isnull=False)
        users = users.filter(home_users | away_users).distinct()
    if not_only_mdcs != 'on':
        users = users.filter(is_mdcs = True)
    if not_active != 'on':
        users = users.filter(user__is_active = True)
    users = users.order_by('-' + point_column, 'id')

    return render_to_response('standings.html', {"users": users, "game_type_id": game_type_id, "game_name": game_name, "form": form},
        context_instance=RequestContext(request))

def recommended(request):
    today = datetime.today()
    recommended_list = Match.objects.filter(date_generated = today)
    recommended = []
    for r in recommended_list:
        recommended.append([r, 0])
    return render_to_response('recommended.html', {"recommended": recommended},
        context_instance=RequestContext(request))

def user(request, user_id):
    user = get_object_or_404(PlayerUserProfile, pk=int(user_id))
    
    ###########################################################################
    ################################ Sah ######################################
    ###########################################################################
    chess = {}
    chess_last_matches = Match.objects.filter(game_type=1).filter(winner__isnull=False).filter(Q(home = user) | Q(away = user)).order_by('-date_played')
    chess["last_match"] = None
    if len(chess_last_matches) > 0:
        chess["last_match"] = chess_last_matches[0]
    chess["standing"] = PlayerUserProfile.objects.filter(chess_points__gt = user.chess_points).order_by('-chess_points').count() + 1
    # meceva odigrano
    chess_matches = Match.objects.filter(game_type=1).filter(winner__isnull=False).filter(Q(home = user) | Q(away = user))
    chess["matches_won"] = 0
    chess["matches_draw"] = 0
    chess["matches_lost"] = 0
    for chess_match in chess_matches:
        if ((user in chess_match.home.all()) and (chess_match.winner == 1)) or ((user in chess_match.away.all()) and (chess_match.winner == 3)):
            chess["matches_won"] += 1
        elif (chess_match.winner == 2):
            chess["matches_draw"] += 1
        else:
            chess["matches_lost"] +=1
    chess["matches_played"] = chess["matches_won"] + chess["matches_draw"] + chess["matches_lost"]

    # odredjujemo najveci i najmanji broj poena
    chess_minimax_points_log = PointsLog.objects.filter(match__game_type=1).filter(user=user).order_by('-points')
    if len(chess_minimax_points_log)>0:
        chess_max_points_log = (chess_minimax_points_log[0].points, chess_minimax_points_log[0].match.date_played)
        chess_min_points_log_temp = chess_minimax_points_log[len(chess_minimax_points_log)-1:][0]
        chess_min_points_log = (chess_min_points_log_temp.points, chess_min_points_log_temp.match.date_played)
        if chess_max_points_log[0] < 1200:
            chess_max_points_log = (1200, user.user.date_joined)
        if chess_min_points_log[0] > 1200:
            chess_min_points_log = (1200, user.user.date_joined)
        if user.chess_points > chess_max_points_log[0]:
            chess_max_points_log = (user.chess_points, datetime.now())
        if user.chess_points < chess_min_points_log[0]:
            chess_min_points_log = (user.chess_points, datetime.now())
    else:
        # nikad ranije nije igrao nijedan mec
        chess_max_points_log = (1200, datetime.now())
        chess_min_points_log = (1200, datetime.now())

    chess["max_points_log"] = chess_max_points_log
    chess["min_points_log"] = chess_min_points_log
    
    ###########################################################################
    ############################ Stoni fudbal #################################
    ###########################################################################
    tf = {}
    tf["standing"] = PlayerUserProfile.objects.filter(tf_points__gt = user.tf_points).order_by('-tf_points').count() + 1

    # odredjujemo najveci i najmanji broj poena
    tf_minimax_points_log = PointsLog.objects.filter(match__game_type=2).filter(user=user).order_by('-points')
    if len(tf_minimax_points_log)>0:
        tf_max_points_log = (tf_minimax_points_log[0].points, tf_minimax_points_log[0].match.date_played)
        tf_min_points_log_temp = tf_minimax_points_log[len(tf_minimax_points_log)-1:][0]
        tf_min_points_log = (tf_min_points_log_temp.points, tf_min_points_log_temp.match.date_played)
        if tf_max_points_log[0] < 1200:
            tf_max_points_log = (1200, user.user.date_joined)
        if tf_min_points_log[0] > 1200:
            tf_min_points_log = (1200, user.user.date_joined)
        if user.tf_points > tf_max_points_log[0]:
            tf_max_points_log = (user.tf_points, datetime.now())
        if user.tf_points < tf_min_points_log[0]:
            tf_min_points_log = (user.tf_points, datetime.now())
    else:
        # nikad ranije nije igrao nijedan mec
        tf_max_points_log = (1200, datetime.now())
        tf_min_points_log = (1200, datetime.now())
    tf["max_points_log"] = tf_max_points_log
    tf["min_points_log"] = tf_min_points_log

    # meceva odigrano
    tf_matches = Match.objects.filter(game_type=2).filter(winner__isnull=False).filter(Q(home = user) | Q(away = user)).distinct()
    tf["matches_won"] = 0
    tf["matches_lost"] = 0
    for tf_match in tf_matches:
        for usertmp in tf_match.home.all():
            if usertmp.id == user.id:
                if tf_match.winner == 1:
                    tf["matches_won"] += 1
                else:
                    tf["matches_lost"] += 1
    for tf_match in tf_matches:
        for usertmp in tf_match.away.all():
            if usertmp.id == user.id:
                if tf_match.winner == 3:
                    tf["matches_won"] += 1
                else:
                    tf["matches_lost"] += 1
    tf["matches_played"] = tf["matches_won"] + tf["matches_lost"]

    tf_last_matches = Match.objects.filter(game_type=2).filter(winner__isnull=False).filter(Q(home = user) | Q(away = user)).order_by('-date_played')
    tf["last_match"] = None
    if len(tf_last_matches) > 0:
        tf["last_match"] = tf_last_matches[0]

    # najcesci saigrac
    teammates = {}
    opponents = {}
    for match in tf_matches:
        user_was_home = False
        for home_user in match.home.all():
            if home_user == user:
                user_was_home = True
                break
        for home_user in match.home.all():
            if home_user == user: continue
            if user_was_home:
                if home_user in teammates:
                    teammates[home_user] += 1
                else:
                    teammates[home_user] = 1
            else:
                if home_user in opponents:
                    opponents[home_user] += 1
                else:
                    opponents[home_user] = 1
        for away_user in match.away.all():
            if away_user == user: continue
            if not user_was_home:
                if away_user in teammates:
                    teammates[away_user] += 1
                else:
                    teammates[away_user] = 1
            else:
                if away_user in opponents:
                    opponents[away_user] += 1
                else:
                    opponents[away_user] = 1

    sorted_by_teammates = sorted(teammates.iteritems(), key = lambda obj: obj[1])
    i = len(sorted_by_teammates) - 2
    while i >= 0 and sorted_by_teammates[-1][1] == sorted_by_teammates[i][1]:
        i = i - 1
    tf["teammates"] = sorted_by_teammates[i+1:]

    sorted_by_opponents = sorted(opponents.iteritems(), key = lambda obj: obj[1])
    i = len(sorted_by_opponents) - 2
    while i >= 0 and sorted_by_opponents[-1][1] == sorted_by_opponents[i][1]:
        i = i - 1
    tf["opponents"] = sorted_by_opponents[i+1:]
    ###########################################################################
    ############################## Fudbal #####################################
    ###########################################################################
    football = {}
    football["standing"] = PlayerUserProfile.objects.filter(football_points__gt = user.football_points).order_by('-football_points').count() + 1

    # odredjujemo najveci i najmanji broj poena
    football_minimax_points_log = PointsLog.objects.filter(match__game_type=3).filter(user=user).order_by('-points')
    if len(football_minimax_points_log)>0:
        football_max_points_log = (football_minimax_points_log[0].points, football_minimax_points_log[0].match.date_played)
        football_min_points_log_temp = football_minimax_points_log[len(football_minimax_points_log)-1:][0]
        football_min_points_log = (football_min_points_log_temp.points, football_min_points_log_temp.match.date_played)
        if football_max_points_log[0] < 1200:
            football_max_points_log = (1200, user.user.date_joined)
        if football_min_points_log[0] > 1200:
            football_min_points_log = (1200, user.user.date_joined)
        if user.tf_points > football_max_points_log[0]:
            football_max_points_log = (user.football_points, datetime.now())
        if user.football_points < football_min_points_log[0]:
            football_min_points_log = (user.football_points, datetime.now())
    else:
        # nikad ranije nije igrao nijedan mec
        football_max_points_log = (1200, datetime.now())
        football_min_points_log = (1200, datetime.now())
    football["max_points_log"] = football_max_points_log
    football["min_points_log"] = football_min_points_log

    # meceva odigrano
    football_matches = Match.objects.filter(game_type=3).filter(winner__isnull=False).filter(Q(home = user) | Q(away = user)).distinct()
    football["matches_won"] = 0
    football["matches_draw"] = 0
    football["matches_lost"] = 0
    for football_match in football_matches:
        for usertmp in football_match.home.all():
            if usertmp.id == user.id:
                if football_match.winner == 1:
                    football["matches_won"] += 1
                elif (football_match.winner == 2):
                    football["matches_draw"] += 1
                else:
                    football["matches_lost"] += 1
    for football_match in football_matches:
        for usertmp in football_match.away.all():
            if usertmp.id == user.id:
                if football_match.winner == 3:
                    football["matches_won"] += 1
                elif (football_match.winner == 2):
                    football["matches_draw"] += 1
                else:
                    football["matches_lost"] += 1
    football["matches_played"] = football["matches_won"] + football["matches_draw"] + football["matches_lost"]

    football_last_matches = Match.objects.filter(game_type=3).filter(winner__isnull=False).filter(Q(home = user) | Q(away = user)).order_by('-date_played')
    football["last_match"] = None
    if len(football_last_matches) > 0:
        football["last_match"] = football_last_matches[0]

    # najcesci saigrac
    teammates = {}
    opponents = {}
    for match in football_matches:
        user_was_home = False
        for home_user in match.home.all():
            if home_user == user:
                user_was_home = True
                break
        for home_user in match.home.all():
            if home_user == user: continue
            if user_was_home:
                if home_user in teammates:
                    teammates[home_user] += 1
                else:
                    teammates[home_user] = 1
            else:
                if home_user in opponents:
                    opponents[home_user] += 1
                else:
                    opponents[home_user] = 1
        for away_user in match.away.all():
            if away_user == user: continue
            if not user_was_home:
                if away_user in teammates:
                    teammates[away_user] += 1
                else:
                    teammates[away_user] = 1
            else:
                if away_user in opponents:
                    opponents[away_user] += 1
                else:
                    opponents[away_user] = 1

    sorted_by_teammates = sorted(teammates.iteritems(), key = lambda obj: obj[1])
    i = len(sorted_by_teammates) - 2
    while i >= 0 and sorted_by_teammates[-1][1] == sorted_by_teammates[i][1]:
        i = i - 1
    football["teammates"] = sorted_by_teammates[i+1:]

    sorted_by_opponents = sorted(opponents.iteritems(), key = lambda obj: obj[1])
    i = len(sorted_by_opponents) - 2
    while i >= 0 and sorted_by_opponents[-1][1] == sorted_by_opponents[i][1]:
        i = i - 1
    football["opponents"] = sorted_by_opponents[i+1:]
    ###########################################################################
    ############################## Basket #####################################
    ###########################################################################
    basket = {}
    basket["standing"] = PlayerUserProfile.objects.filter(basket_points__gt = user.basket_points).order_by('-basket_points').count() + 1

    # odredjujemo najveci i najmanji broj poena
    basket_minimax_points_log = PointsLog.objects.filter(match__game_type=4).filter(user=user).order_by('-points')
    if len(basket_minimax_points_log)>0:
        basket_max_points_log = (basket_minimax_points_log[0].points, basket_minimax_points_log[0].match.date_played)
        basket_min_points_log_temp = basket_minimax_points_log[len(basket_minimax_points_log)-1:][0]
        basket_min_points_log = (basket_min_points_log_temp.points, basket_min_points_log_temp.match.date_played)
        if basket_max_points_log[0] < 1200:
            basket_max_points_log = (1200, user.user.date_joined)
        if basket_min_points_log[0] > 1200:
            basket_min_points_log = (1200, user.user.date_joined)
        if user.basket_points > basket_max_points_log[0]:
            basket_max_points_log = (user.basket_points, datetime.now())
        if user.basket_points < basket_min_points_log[0]:
            basket_min_points_log = (user.basket_points, datetime.now())
    else:
        # nikad ranije nije igrao nijedan mec
        basket_max_points_log = (1200, datetime.now())
        basket_min_points_log = (1200, datetime.now())
    basket["max_points_log"] = basket_max_points_log
    basket["min_points_log"] = basket_min_points_log

    # meceva odigrano
    basket_matches = Match.objects.filter(game_type=4).filter(winner__isnull=False).filter(Q(home = user) | Q(away = user)).distinct()
    basket["matches_won"] = 0
    basket["matches_lost"] = 0
    for basket_match in basket_matches:
        for usertmp in basket_match.home.all():
            if usertmp.id == user.id:
                if basket_match.winner == 1:
                    basket["matches_won"] += 1
                else:
                    basket["matches_lost"] += 1
    for basket_match in basket_matches:
        for usertmp in basket_match.away.all():
            if usertmp.id == user.id:
                if basket_match.winner == 3:
                    basket["matches_won"] += 1
                else:
                    basket["matches_lost"] += 1
    basket["matches_played"] = basket["matches_won"] + basket["matches_lost"]

    basket_last_matches = Match.objects.filter(game_type=4).filter(winner__isnull=False).filter(Q(home = user) | Q(away = user)).order_by('-date_played')
    basket["last_match"] = None
    if len(basket_last_matches) > 0:
        basket["last_match"] = basket_last_matches[0]

    # najcesci saigrac
    teammates = {}
    opponents = {}
    for match in basket_matches:
        user_was_home = False
        for home_user in match.home.all():
            if home_user == user:
                user_was_home = True
                break
        for home_user in match.home.all():
            if home_user == user: continue
            if user_was_home:
                if home_user in teammates:
                    teammates[home_user] += 1
                else:
                    teammates[home_user] = 1
            else:
                if home_user in opponents:
                    opponents[home_user] += 1
                else:
                    opponents[home_user] = 1
        for away_user in match.away.all():
            if away_user == user: continue
            if not user_was_home:
                if away_user in teammates:
                    teammates[away_user] += 1
                else:
                    teammates[away_user] = 1
            else:
                if away_user in opponents:
                    opponents[away_user] += 1
                else:
                    opponents[away_user] = 1

    sorted_by_teammates = sorted(teammates.iteritems(), key = lambda obj: obj[1])
    i = len(sorted_by_teammates) - 2
    while i >= 0 and sorted_by_teammates[-1][1] == sorted_by_teammates[i][1]:
        i = i - 1
    basket["teammates"] = sorted_by_teammates[i+1:]

    sorted_by_opponents = sorted(opponents.iteritems(), key = lambda obj: obj[1])
    i = len(sorted_by_opponents) - 2
    while i >= 0 and sorted_by_opponents[-1][1] == sorted_by_opponents[i][1]:
        i = i - 1
    basket["opponents"] = sorted_by_opponents[i+1:]
    # ovi poeni zasluzuju objasnjenje - posto nam u template-u trebaju i prethodni i trenutni poeni posle meca,
    # zipujemo dve liste - listu poena i listu poena pomerenu za jedno mesto. Na taj nacin {% for %} petlja
    # u template-u moze u jednoj iteraciji da pokupi obe vrednosti za poene
    point_logs = PointsLog.objects.filter(user = user).order_by('-match__date_played'). order_by('-id')
    point_logs_shifted = list(point_logs)[:-1]
    point_logs_shifted.insert(0,None)
    point_logs = zip(point_logs, point_logs_shifted)
    
    return render_to_response('user.html',
        {"user_object": user, "chess": chess, "tf": tf, "football": football, "basket": basket, "point_logs": point_logs},
        context_instance=RequestContext(request))

def compare_users(request, game_type, user1_id, user2_id):
    game_type_id = 1
    game_name = ""
    if game_type == "chess":
        game_type_id = 1
        game_name = "šah"
    elif game_type == "table_football":
        game_type_id = 2
        game_name = "stoni fudbal"
    elif game_type == "football":
        game_type_id = 3
        game_name = "fudbal"
    elif game_type == "basketball":
        game_type_id = 4
        game_name = "basket"
    else:
        raise Http404('Unknown game type "%s"' % game_type)

    user1 = get_object_or_404(PlayerUserProfile, pk=int(user1_id))
    user2 = get_object_or_404(PlayerUserProfile, pk=int(user2_id))
    if user1 == user2:
        messages.add_message(request, messages.INFO, 'Ne možete upoređivati dva ista igrača')
        return HttpResponseRedirect(reverse('mdcssport.mdcsapp.views.head2head'))
    
    allMatches = Match.objects.filter(game_type=game_type_id).filter(winner__isnull=False)
    if game_type_id == 1:
        standing1 = PlayerUserProfile.objects.filter(chess_points__gt = user1.chess_points).order_by('-chess_points').count() + 1
        standing2 = PlayerUserProfile.objects.filter(chess_points__gt = user2.chess_points).order_by('-chess_points').count() + 1
    elif game_type_id == 2:
        standing1 = PlayerUserProfile.objects.filter(tf_points__gt = user1.tf_points).order_by('-tf_points').count() + 1
        standing2 = PlayerUserProfile.objects.filter(tf_points__gt = user2.tf_points).order_by('-tf_points').count() + 1
    elif game_type_id == 3:
        standing1 = PlayerUserProfile.objects.filter(football_points__gt = user1.football_points).order_by('-football_points').count() + 1
        standing2 = PlayerUserProfile.objects.filter(football_points__gt = user2.football_points).order_by('-football_points').count() + 1
    elif game_type_id == 4:
        standing1 = PlayerUserProfile.objects.filter(basket_points__gt = user1.tf_points).order_by('-basket_points').count() + 1
        standing2 = PlayerUserProfile.objects.filter(basket_points__gt = user2.tf_points).order_by('-basket_points').count() + 1
    else:
        raise Http404('Unknown game type "%s"' % game_type)

    h2hMatches = Match.objects.filter(game_type=game_type_id).filter(winner__isnull=False).filter(Q(home=user1,away=user2) | Q(home=user2,away=user1)).order_by('date_played');
    statisticsH2H = UserMatchStatistics(user1, h2hMatches)
    statistics1 = UserMatchStatistics(user1, allMatches)
    statistics2 = UserMatchStatistics(user2, allMatches)
    return render_to_response('head2head.html', {"h2hMatches": h2hMatches,
                                                 "statisticsH2H":statisticsH2H,
                                                 "statistics1":statistics1,
                                                 "statistics2":statistics2,
                                                 "user1":user1,
                                                 "user2":user2,
                                                 "standing1":standing1, 
                                                 "standing2":standing2,
                                                 "game_type":game_type,
                                                 "game_type_id": game_type_id},
        context_instance=RequestContext(request))

def head2head(request):
    users = PlayerUserProfile.objects.all()
    sports = (("chess", "Šah"), ("table_football", "Stoni fudbal"), ("football", "Fudbal"), ("basketball", "Basket"))
    return render_to_response('h2h.html', {"users" : users, "sports": sports},
        context_instance=RequestContext(request))

def timeline(request, game_type):
    game_name = ""
    if game_type == "chess":
        game_name = "šah"
    elif game_type == "table_football":
        game_name = "stoni fudbal"
    elif game_type == "football":
        game_name = "fudbal"
    elif game_type == "basketball":
        game_name = "basket"
    else:
        raise Http404('Unknown game type "%s"' % game_type)
    timeline_url = None
    if len(request.GET) > 0:
        form = UserSelect(request.GET)
        if form.is_valid():
            timeline_url = "/mdcs/statistics/" + game_type + "/timeline.png?users="
            timeline_url += reduce(lambda x, y: x + "," + y, [str(user.id) for user in form.cleaned_data["users"]])
    else:
        form = UserSelect()
    return render_to_response('timeline.html', {"form": form, "game_name": game_name, "timeline_url": timeline_url},
        context_instance=RequestContext(request))